package com.googlecode.imanager.swing.form;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.googlecode.imanager.client.bridge.form.ITextArea;
import com.googlecode.imanager.client.form.TextArea;
import com.googlecode.imanager.client.form.WrapMode;
import com.googlecode.imanager.core.base.BridgeApplication;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class SwingTextArea extends SwingInputText implements ITextArea {

    private FocusKeyListener focusKeyListener;
    private JScrollPane scrollPane;
    
    public SwingTextArea(BridgeApplication bridge, TextArea source) {
        super(bridge, source);
    }

    @Override
    protected void buildImplementation() {
        focusKeyListener = new FocusKeyListener();
        scrollPane = new JScrollPane();
        scrollPane.setViewportView(target);
        super.buildImplementation();
    }

    @Override
    protected JTextArea createTarget() {
        return new JTextArea();
    }

    @Override
    public JTextArea getTarget(){
        return (JTextArea) target;
    }

    @Override
    public JScrollPane getTargetContained() {
        return scrollPane;
    }
    
    @Override
    public TextArea getSource() {
        return (TextArea) source;
    }

    @Override
    protected void doAttachKeyEvents() {
        getTarget().addKeyListener(focusKeyListener);
        super.doAttachKeyEvents();
    }

    @Override
    public void setMaxLength(Integer maxLength) {
        getTarget().setColumns(maxLength == null ? 0 : maxLength);
    }

    @Override
    public void setWantTabKeys(Boolean wantTabKeys) {
        focusKeyListener.setEnabled(!Boolean.TRUE.equals(wantTabKeys));
    }

    @Override
    public void setWrapMode(WrapMode wrapMode) {
        if (wrapMode == null){
            wrapMode = WrapMode.DEFAULT;
        }
        switch (wrapMode) {
            case NO_WRAP:
                getTarget().setLineWrap(false);
                break;

            case WORD_WRAP:
                getTarget().setLineWrap(true);
                getTarget().setWrapStyleWord(true);
                break;
                
            default:
                getTarget().setLineWrap(true);
                getTarget().setWrapStyleWord(false);
                break;
        }
    }

    
    private class FocusKeyListener implements KeyListener {
        
        private boolean enabled;
        private boolean consumed;

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
            this.consumed = false;
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (enabled
                    && e.getKeyCode() == KeyEvent.VK_TAB
                    && !e.isControlDown()
                    && !e.isMetaDown()
                    && !e.isAltDown()
                    && !e.isAltGraphDown()){
                e.consume();
                
                if (e.isShiftDown()){
                    getTarget().transferFocusBackward();
                } else {
                    getTarget().transferFocus();
                }
                
                consumed = true;
            }
            
            consumed = false;
        }

        @Override
        public void keyReleased(KeyEvent e) {
            if (consumed){
                e.consume();
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            if (consumed){
                e.consume();
            }
        }
        
    }
    
}
